From CPOA : les premiers patrons

Suivre ces slides sur Internet…​

http://bit.ly/jmb-cpoa
http://bit.ly/jmb-cpoa
http://iut-blagnac.github.io/cpoa/

Plan

-

Introduction

Ce cours porte sur la Conception et Programmation Objet Avancée.

Concepts objets

Vous avez appris (cf. M2103 et M2104) un certain nombre de concepts objets :

Abstraction

Définition :

Abstraction

Définition (restrictive) :

Une classe est une abstraction des caractéristiques communes d’un ensemble d’objets.

Encapsulation

Définition :

Encapsulation

Définition (restrictive) :

Dans la description d’un objet, le but de l'encapsulation est de masquer les attributs et les méthodes, c’est-à-dire, la manière dont est réalisé le comportement de l’objet.

Héritage

Définition :

Héritage

Définition (simpliste) :

L’héritage est la transmission de caractéristiques à ses descendants.

La classe qui hérite dispose des méthodes et attributs de niveau public et protected de sa classe mère.

Polymorphisme

Le nom de polymorphisme vient du grec :

Polymorphisme

Le nom de polymorphisme vient du grec :

qui peut prendre plusieurs formes

L’héritage concerne les classes, le polymorphisme concerne les objets.

Polymorphisme (suite)

On distingue généralement trois types de polymorphisme :

Polymorphisme ad hoc

int method(int,int);
int method(int);
int method(float,float);

Le polymorphisme paramétrique

Appelé aussi généricité.

interface Iterator<E> {
    boolean hasNext();
    E next();
}

public <T> static void copy(Collection<? extends T> source, Collection<? super T> dest) {
    for (T t : source) {
         dest.add(t);
    }
}

Le polymorphisme d’héritage

Objectifs de la conception objet

On essaye d’éviter trois problèmes principaux du développement :

La rigidité
Anticiper les évolutions susceptibles d’impacter l’application.
La fragilité
Eviter les erreurs provoquées par la modification d’une partie du code.
L’immobilité
Rendre moins difficile l’extraction d’une partie du code.

Bonnes pratiques et patrons

Pour répondre aux problèmes ci-dessus, on va s’attaquer à diminuer les dépendances et éviter l'"effet spaghetti".

Les qualités recherchées sont :

Bonnes pratiques et patrons (suite)

Nous allons apprendre des bonnes pratiques :

Bonnes pratiques et patrons (suite)

L’étape suivante consiste à apprendre les bonnes solutions de conception, ce qu’on appelle les patrons de conception (ou design patterns en anglais).

Organisation du cours

Rappel du rythme : 1 cours, 1 TD et 2 TPs par semaine. Pendant 8 semaines.

Organisation (suite)

Voici une proposition de déroulement des semaines :

Semaine 1
SuperCanard, le grand classique, [strategy]
Semaine 2
Semaine 3
Patrons [Fabrique], [Proxy], [Etat]
Semaine 4
  • [Observateur]
    • version intuitive (2 interfaces)
    • version Java (classe Observable)
Semaine 5
L’exemple de Meyer : menus en objet
Semaine 6
  • Patrons Décorateur, Façade, Visiteur
  • MVC avec l’exemple JTable de Java
  • Patrons Chaîne de responsabilité (juste en cours)
Semaines 7 et 8
  • Quelques idées de projet final :
    • Refactorer un code généré par Umple.
    • Refactorer le code de MPA (mais pas le leur, celui d’un autre groupe)

Evaluation et notation

Comme prévu par le planning des contrôles, les étudiants auront :

Rappels sur des éléments Java importants

Importance du typage

Différents types de typage

Le fait d’attribuer un type (une classe) à une variable (un objet) peut se faire de plusieurs façons :

Typage statique

On parle de typage statique quand la majorité des vérifications de type sont effectuées au moment de la compilation.

Exemple de typage statique
int i = 0;  // cette déclaration indique explicitement que
            // la variable i est de type entier

Typage dynamique

Le typage dynamique consiste à laisser l’ordinateur réaliser l’opération de typage à la volée, lors de l’exécution du code.

Typage dynamique (exemple)

Exemple de typage dynamique
/**
 * @author André Peninou
 */
public class Type {
  void m() {
    System.out.println ("Type");
    }
}
public class SousType extends Type {
  void m() {
    System.out.println ("SousType");
  }
  void autreM(){
    System.out.println ("Spécifique SousType");
  }
}
...
    Type a = new Type();
    a.m(); // "Type"

    a = new SousType();
    a.m(); // "SousType"
    // Statique : a est un Type (à la compil)
    // Dynamique : a est un SousType au runtime.

    // D'où :
    a = new SousType();
    a.autreM();
    // NOK car type statique == A => autreM() n'existe pas à la compilation
...

Duck typing

Style de typage dynamique où la sémantique d’un objet (c’est-à-dire son type) est déterminée par l’ensemble de ses méthodes et de ses attributs, et non par un type défini et nommé explicitement par le programmeur.

L’origine de cette expression est liée à cette citation :

Si je vois un animal qui vole comme un canard, cancane comme un canard, et nage comme un canard, alors j’appelle cet oiseau un canard.


James Whitcomb Riley

Duck typing (exemple)

Exemple de duck typing en Ruby
def calcule(a, b, c)
  return a*b+c
end

$a = calcule(6, 3, 2)
$b = calcule('6', 3, ', the number of the beast')

puts $a.to_s
puts $b.to_s

Ce qui donne :

20
666, the number of the beast
Pour aller plus loin : http://fr.wikipedia.org/wiki/Duck_typing

Importance de la visibilité

Dès que l’on commence à avoir une application conséquente, l’organisation en package devient obligatoire. Revenons donc sur les questions de visibilité des propriétés et méthodes, qui seront importants dans la plupart des aspects de ce module.

Si un champ d’une classe A :

Ci-dessus, les niveaux de visibilité sont rangés par visibilité croissante.

Importance de la visibilité (exemple)

package UN;
public class A {
  protected String attrprotected;
  String attrfriend; // friend
}

Si on définit une deuxième classe dans le même package :

package UN;
  class B {
    ...
    {
        A a = new A ();
        a.attrprotected// OK : même si bizarre
        a.attrfriend  // OK : visible package
    }
  }

package UN;
  class C extends A {
    ...
    {
        this.attrprotected// OK : normal
        this.attrfriend // OK : visible package
    }
  }

Importance de la visibilité (suite de l’exemple)

package DEUX;
  class B {
      ...
    {
        A a = new A ();
        a.attrprotected// NON OK : normal
        a.attrfriend  // NON OK : normal, proche de "private"
    }
  }

  class C extends A {
      ...
    {
        this.attrprotected// OK : normal car protected et héritage
        this.attrfriend // NON OK : normal, proche de "private"
    }
  }

Alors private ou protected ?

À la question private ou protected ? Quel est le mieux pour les attributs ?

Visibilité et UML

Il n’y a pas de visibilité par défaut en UML™.

Retour sur les Membres static

class VariableDemo
{
  static int count=0;
  public void increment()
  {
    count++;
  }
  public static void main(String args[])
  {
    VariableDemo obj1=new VariableDemo();
    VariableDemo obj2=new VariableDemo();
    obj1.increment();
    obj2.increment();
    System.out.println("Obj1: count is="+obj1.count);
    System.out.println("Obj2: count is="+obj2.count);
  }
}

Output:

Obj1: count is=2
Obj2: count is=2

Membres static (suite)

Comment ça marche :

Méthodes static

import java.lang.Math;

class Another {
  public static void main(String[] args) {
    int result;

    result = Math.min(10, 20); //calling static method min by writing class name

    System.out.println(result);
    System.out.println(Math.max(100, 200));
  }
}

Méthodes static et appel aux méthodes non-statiques

public class Main {
    public static void main(String[] args) {
        Main p = new Main();
        k();
    }

    protected Main() {
        System.out.print("1234");
    }

    protected void k() {
    }
}

À l’exécution :

Main p = new Main();  // => prints 1234
k()                   // => raises error

Méthodes static et appel aux méthodes non-statiques (suite)

Static method cannot call non-static methods

Bien sûr que si, sauf qu’il faut que cette dernière porte sur une instance de la classe.

Méthodes static et appel aux méthodes non-statiques (suite)

Constructors are kind of a method with no return type.

En fait il vaudrait mieux les considérer comme une sorte de méthode statique. En effet elle ne requièrent pas de porter sur un objet!

cf. la discussion http://stackoverflow.com/questions/10513633/static-method-access-to-non-static-constructor

Utilité générale des enum

Modélisation

Le type enumération est souvent utilisé en modélisation :

enum

Propriétés

public enum Civilite {
  MADAME, MONSIEUR
}

Méthodes de base

Exemple plus complexe

public enum Langage {
  //Objets directement construits
  JAVA("Langage JAVA", "Eclipse"),
  C ("Lanage C", "Code Block"),
  CPlus ("Langage C++", "Visual studio"),
  PHP ("Langage PHP", "PS Pad");

  private String name = "";
  private String editor = "";

  //Constructeur
  Langage(String name, String editor){
    this.name = name;
    this.editor = editor;
  }

  public void getEditor(){
    System.out.println("Editeur : " + editor);
  }

  public String toString(){
    return name;
  }

  public static void main(String args[]){
    Langage l1 = Langage.JAVA;
    Langage l2 = Langage.PHP;

    l1.getEditor();
    l2.getEditor();
  }
}

Questions?

Time for a quizz!

QUESTION
  • Connectez-vous sur : http://www.socrative.com/ (student login)
  • Ou téléchargez l’application pour étudiant socrative2
  • Choisissez la room 44918d67
socrative1